#pragma once
#include "hv/TcpServer.h"
#include <QtWidgets/QMainWindow>
#include <QPushButton>
#include <QLabel>
#include <QLineEdit>
#include <QMap>
#include <json/json.h>
#include <unordered_map>
#include <chrono>
#include <string>

#include <hv/EventLoop.h>
#include <hv/EventLoopThread.h>

struct ClientInfo {
    hv::SocketChannelPtr channel;
    std::chrono::steady_clock::time_point lastHeartbeatTime;
};

enum class module {       //连接服务器的客户端的名称
    CONPRODUCT,           //消息制造端 (发送者)
    WEATHERMODULE         //天气模块（接收者）
};

enum class cmd {
    INITCONNECT,            //初始化连接（cmd，name）
    DISCONNECT,
    HEARTBEAT,
    SEND,                  //转发消息（cmd，sender，receiver，content）
    SENDIMG,
    SENDPDFFILE
};
class QTextEdit;
class QTableWidget;
class TServerWidget : public QMainWindow
{
    Q_OBJECT

public:
    TServerWidget(QWidget *parent = nullptr);
    ~TServerWidget();

    bool start(int port, const char* host = "0.0.0.0");
    void stop();

private:
    void initUI();
    void initConnect();
    cmd intTocmd(int i);
    void deleteClientFromMap(const std::string& name);
    void savePdfFile(const std::string& content, const std::string& fileName);
    void saveImage(const std::string& image, const std::string& imageName);
    void sendMsgToReceiver(Json::Value receivers, Json::Value content);
    void addClientToMap(const std::string& name, const hv::SocketChannelPtr& channel);
    bool stringToImage(const std::string& base64Image, const std::string& name);
    void heartBeat(const std::string& name);
    void checkHeartbeats();

    QPushButton* m_pStart;
    QPushButton* m_pEnd;
    QLabel* m_pHost;
    QLabel* m_pPort;
    QLineEdit* m_pHostLine;
    QLineEdit* m_pPortLine;
    QTextEdit* m_pTipsBox;
    QTableWidget* m_pClientMapWidget;

    hv::TcpServer* server;
    std::unordered_map<std::string, ClientInfo> clientMap;
    std::string incompleteMessageBuffer;
    int row = 0;

    hv::EventLoopPtr m_HeartBeatLoop;
    hv::EventLoopThread m_HeartBeatLoopThread;
};
